﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using UpGrade;

namespace CID_Server
{
    public partial class Form_CID_Server : Form
    {
        public Form_CID_Server()
        {
            InitializeComponent();
        }


        private UdpClient udp_250;
        private Thread thread_250;
        private static bool Stop_250 = false;
        int Rxcount = 0;
        byte[] rxBuffer = new byte[160 * 1024];
        byte[] lastRxBu = new byte[160 * 1024];
        string lastSts_120 = "";

        private UdpClient udp_120;
        private Thread thread_120;
        private static bool Stop_120 = false;

        private UdpClient udpcSend;
        byte[] frameBuffer = new byte[160 * 1024];
        private short TxFrameIndex = 0;

        bool isRunning = false;
        string IP_120 = "192.168.0.120";
        string IP_250 = "192.168.0.250";
        string IP_CID = "192.168.0.110";





        private void button_start_Click(object sender, EventArgs e)
        {
            if (isRunning)
            {
                groupBox_show.Enabled = true ;
                checkBox_ack.Enabled = true;
                RequesThreadStop();
                button_start.Text = "Off";
                button_start.BackColor = Color.Gray;
                isRunning = false;
            }
            else
            {
                groupBox_show.Enabled = false;
                checkBox_ack.Enabled = false;
                ReceiveThreadStart();
                button_start.Text = "On";
                button_start.BackColor = Color.Green;
                isRunning = true;
                button_TCP.Enabled = true;
                groupBox_show_SizeChanged(null, null);
            }
        }

        private void ReceiveThreadStart()
        {

            if (checkBox_ack.Checked)
            {
                IPEndPoint localIpep_250 = new IPEndPoint(
                        IPAddress.Parse(IP_250), 5555); // 本机IP和监听端口号
                udp_250 = new UdpClient(localIpep_250);
                thread_250 = new Thread(ReceiveThread_250);
                Stop_250 = false;
                thread_250.Start();
            }

            IPEndPoint localIpep_120 = new IPEndPoint(
                    IPAddress.Parse(IP_120), 5555); // 本机IP和监听端口号
            udp_120 = new UdpClient(localIpep_120);
            thread_120 = new Thread(ReceiveThread_120);
            Stop_120 = false;
            thread_120.Start();

        }

        private void RequesThreadStop()
        {
            if (udp_250 != null)
            {
                udp_250.Close();
                Stop_250 = true;
                while (thread_250.IsAlive)
                {
                    Thread.Sleep(1);
                    thread_250.Join();
                    thread_250.Abort();
                }
            }

            if (udp_120 != null)
            {
                udp_120.Close();
                Stop_120 = true;
                while (thread_120.IsAlive)
                {
                    Thread.Sleep(1);
                    thread_120.Join();
                    thread_120.Abort();
                }
            }
        }

        private void ReceiveThread_120(object obj)
        {
            const int AB_DATA_OFFSET = 72;
            IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, 0);
            while (!Stop_120)
            {
                try
                {
                    byte[] bytRecv = udp_120.Receive(ref remoteIpep);
                    if (bytRecv.Length > 0)
                    {
                        string str = System.Text.Encoding.ASCII.GetString(bytRecv);

                        this.Invoke(new MethodInvoker(delegate
                        {
                            if (str.StartsWith("RealTimeSts"))
                            {
                                richTextBox_120.AppendText("\r\n");
                                #region RealTimeSts
                                for (int i = 0; i < str.Length - 2; i++)
                                {
                                    if (str.Length > (13 + 3 * (15 + 5 + 4 + 9 + 128 + 10 + 1)) + 2)
                                    {
                                        #region 13版解析
                                        const int indexJD = 13 + 3 * 15;//交大帧数据开始
                                        const int indexLON = indexJD + 3 * 5;//交大帧数据开始
                                        if (i == indexJD)//交大帧数据开始
                                        {
                                            richTextBox_120.AppendText("[交大]");
                                        }
                                        else if (i == indexLON)//长龙协议 帧数量 帧0长度
                                        {
                                            richTextBox_120.AppendText("[长龙]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4)))//命令开始 帧序号 机车号 设备号
                                        {
                                            richTextBox_120.AppendText("[命令]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9)))//实时数据开始
                                        {
                                            richTextBox_120.AppendText("[实时数据]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 8)))//帧序号 类型 板卡
                                        {
                                            richTextBox_120.AppendText("\r\n帧状态]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 19)))//AWK BWK
                                        {
                                            richTextBox_120.AppendText("[AWK]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 38)))//AKZ
                                        {
                                            richTextBox_120.AppendText("\r\n[AKZ]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 38 + AB_DATA_OFFSET)))//BKZ
                                        {
                                            richTextBox_120.AppendText("\r\n[BKZ]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 50)))//A_export
                                        {
                                            richTextBox_120.AppendText("[EX]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 50 + AB_DATA_OFFSET)))//B_export
                                        {
                                            richTextBox_120.AppendText("[EX]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 70)))//A_JM1
                                        {
                                            richTextBox_120.AppendText("[JM]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 70 + AB_DATA_OFFSET)))//B_JM1
                                        {
                                            richTextBox_120.AppendText("[JM]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 200)))//TAX39
                                        {
                                            richTextBox_120.AppendText("\r\n[TAX39]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 226)))//TAX39
                                        {
                                            richTextBox_120.AppendText("\r\n[TAX38]");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 256)))//TAX38
                                        {
                                            richTextBox_120.AppendText("\r\n[BJ]");
                                        }
                                        #endregion
                                    }
                                    else
                                    {
                                        #region 08版解析
                                        if (i == (13 + 3 * 15))//交大帧数据开始
                                        {
                                            richTextBox_120.AppendText("\r\n交大：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5)))//长龙协议 帧数量 帧0长度
                                        {
                                            richTextBox_120.AppendText("\r\n长龙：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4)))//命令开始 帧序号 机车号 设备号
                                        {
                                            richTextBox_120.AppendText("\r\n命令：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9)))//实时数据开始
                                        {
                                            richTextBox_120.AppendText("\r\n实时数据：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 8)))//灯显开始
                                        {
                                            richTextBox_120.AppendText("\r\n解码灯显：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 17)))//信息报告开始
                                        {
                                            richTextBox_120.AppendText("\r\n信息报告：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 26)))//幅度开始
                                        {
                                            richTextBox_120.AppendText("\r\n制式幅度：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 35)))//状态
                                        {
                                            richTextBox_120.AppendText("\r\n本帧状态：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 36)))//频偏
                                        {
                                            richTextBox_120.AppendText("\r\n频偏无关：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 38)))//监控开始
                                        {
                                            richTextBox_120.AppendText("\r\n监控板卡：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 39)))//监控温度
                                        {
                                            richTextBox_120.AppendText("\r\n监控温度：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 47)))//运行开始
                                        {
                                            richTextBox_120.AppendText("\r\n系统运行：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 59)))//110V电源开始
                                        {
                                            richTextBox_120.AppendText("\r\n电源电压：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 64)))//TAX
                                        {
                                            richTextBox_120.AppendText("\r\nTAX2数据：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 124)))//司控I/II端
                                        {
                                            richTextBox_120.AppendText("\r\n司控电压：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 126)))//校验
                                        {
                                            richTextBox_120.AppendText("\r\n校验验证：");
                                        }
                                        else if (i == (13 + 3 * (15 + 5 + 4 + 9 + 128)))//报警
                                        {
                                            richTextBox_120.AppendText("\r\n报警代码：");
                                        }
                                        #endregion
                                    }


                                    if (i < lastSts_120.Length)
                                    {
                                        if (lastSts_120[i] == str[i])
                                        {
                                            richTextBox_120.SelectionColor = Color.Black;
                                            richTextBox_120.SelectionBackColor = Color.White;
                                            richTextBox_120.AppendText((str[i].ToString()));
                                            continue;
                                        }
                                    }
                                    richTextBox_120.SelectionColor = Color.DarkRed;
                                    richTextBox_120.SelectionBackColor = Color.LightGreen;
                                    richTextBox_120.AppendText((str[i].ToString()));
                                }
                                lastSts_120 = str;
                                richTextBox_120.AppendText("\r\n");
                                #endregion
                            }
                            else
                            {
                                richTextBox_120.AppendText(str);
                            }

                            SaveInfile(" test.txt", str);
                            if (richTextBox_120.Text.Length > 500000)
                                richTextBox_120.Text = richTextBox_120.Text.Substring(490000);


                            richTextBox_120.ScrollToCaret();
                        }));

                    }

                }
                catch (Exception)//Exception ex)
                {
                    //throw new Exception(ex.ToString());
                }
            }
        }

        private void ReceiveThread_250(object obj)
        {
            IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, 0);
            while (!Stop_250)
            {
                try
                {
                    byte[] bytRecv = udp_250.Receive(ref remoteIpep);
                    if (bytRecv.Length > 0)
                    {
                        for (int i = 0; i < bytRecv.Length; i++)
                        {
                            rxBuffer[i] = bytRecv[i];
                        }
                        Rxcount++;
                        this.Invoke(new MethodInvoker(delegate
                        {
                            #region box display
                            richTextBox_250.AppendText((Rxcount.ToString() + ":>").PadRight(6, ' '));
                            richTextBox_250.SelectionColor = Color.Black;
                            richTextBox_250.SelectionBackColor = Color.LightPink;
                            richTextBox_250.AppendText("03 04 05 06 07 08 09 10 11 12 13 14 15 16");
                            richTextBox_250.SelectionBackColor = Color.White;
                            richTextBox_250.AppendText(" ");
                            richTextBox_250.SelectionBackColor = Color.LightPink;
                            richTextBox_250.AppendText("01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16");
                            richTextBox_250.SelectionBackColor = Color.White;
                            richTextBox_250.AppendText(" ");
                            richTextBox_250.SelectionBackColor = Color.LightPink;
                            richTextBox_250.AppendText("01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16");
                            richTextBox_250.SelectionBackColor = Color.White;
                            richTextBox_250.AppendText(" ");
                            richTextBox_250.SelectionBackColor = Color.LightPink;
                            richTextBox_250.AppendText("01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16\r\n");


                            for (int i = 0; i < bytRecv.Length; i++)
                            {
                                if (bytRecv[i] == lastRxBu[i])
                                {
                                    richTextBox_250.SelectionColor = Color.Black;
                                    richTextBox_250.SelectionBackColor = Color.White;
                                }
                                else
                                {
                                    richTextBox_250.SelectionColor = Color.DarkRed;
                                    richTextBox_250.SelectionBackColor = Color.LightGreen;
                                    lastRxBu[i] = bytRecv[i];
                                }
                                richTextBox_250.AppendText(bytRecv[i].ToString("X2"));

                                richTextBox_250.SelectionColor = Color.Black;
                                richTextBox_250.SelectionBackColor = Color.White;
                                richTextBox_250.AppendText(" ");
                            }
                            richTextBox_250.AppendText("\r\n");

                            if (richTextBox_250.Text.Length > 50000)
                                richTextBox_250.Text = richTextBox_250.Text.Substring(49000);

                            richTextBox_250.ScrollToCaret();
                            #endregion
                        }));

                        if (checkBox_ack.Checked)
                            FrameHandler(bytRecv.Length);
                    }

                    //------------------------------------------------------------------------------
                    

                }
                catch (Exception)//Exception ex)
                {
                    //throw new Exception(ex.ToString());
                }
            }
        }

        private void FrameHandler(int length)
        {
            {
                frameBuffer[0] = 0x55;
                frameBuffer[1] = 0xAA;
                frameBuffer[2] = 0x01;
                frameBuffer[3] = 0x0F;
                frameBuffer[4] = 0x01;
                frameBuffer[5] = (byte)(14 & 0xFF);
                frameBuffer[6] = (byte)(14 >> 8);
                frameBuffer[7] = (byte)(TxFrameIndex & 0xFF);//framendex
                frameBuffer[8] = (byte)(TxFrameIndex++ >> 8);
                frameBuffer[9] = 0x09;
                frameBuffer[10] = 0x07;
                frameBuffer[11] = 0x00;
                frameBuffer[12] = 0x00;
                frameBuffer[13] = 0x00;
                frameBuffer[14] = 0x00;


                frameBuffer[15] = frameBuffer[5];
                frameBuffer[16] = frameBuffer[6];
                frameBuffer[17] = 0x09;
                frameBuffer[18] = 0x05;
                frameBuffer[19] = 0x01;

                frameBuffer[20] = (byte)(DateTime.Now.Year - 2000);     //Year
                frameBuffer[21] = (byte)DateTime.Now.Month;    //Month
                frameBuffer[22] = (byte)DateTime.Now.Day;      //Day
                frameBuffer[23] = (byte)DateTime.Now.Hour;     //Hour
                frameBuffer[24] = (byte)DateTime.Now.Minute;   //Minute
                frameBuffer[25] = (byte)DateTime.Now.Second;   //Second

                frameBuffer[26] = 0x01;
                frameBuffer[27] = rxBuffer[7];                  
                frameBuffer[28] = rxBuffer[8];

                frameBuffer[29] = 0;
                for (int i = 0; i < 29; i++)
                {
                    frameBuffer[29] += frameBuffer[i];
                }

                frameBuffer[29] = (byte)~frameBuffer[29];
                frameBuffer[29]++;

                IPEndPoint localIpep = new IPEndPoint(IPAddress.Parse(IP_250), 12375); // 本机IP，指定的端口号
                udpcSend = new UdpClient(localIpep);
                IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(IP_CID), 5555); // 发送到的IP地址和端口号

                udpcSend.Send(frameBuffer, 30, remoteIpep);
                udpcSend.Close();
            }
        }

        private void SaveInfile(string filename,string mes)
        {
            #region Save fileSaveStr
            string path_dir = Application.StartupPath + "\\RecData\\";
            if (!Directory.Exists(path_dir))
                Directory.CreateDirectory(path_dir);

            filename =  DateTime.Now.Year.ToString("00") +
                        DateTime.Now.Month.ToString("00") +
                        DateTime.Now.Day.ToString("00") +
                        filename;
            using (FileStream fs1 = new FileStream(Application.StartupPath + @"\RecData\" + filename, FileMode.OpenOrCreate))
            {
                TextWriter w1 = new StreamWriter(fs1, Encoding.Default);
                fs1.Seek(0, SeekOrigin.End);
                w1.WriteLine(DateTime.Now.ToString() + " :\r\n" + mes);
                w1.Close();
                fs1.Close();
            }
            #endregion
        }

        private void Form_CID_Server_FormClosing(object sender, FormClosingEventArgs e)
        {
            RequesThreadStop();
        }

        private void button_cls_Click(object sender, EventArgs e)
        {
            richTextBox_250.Clear();
            richTextBox_120.Clear();
        }

        private void groupBox_show_SizeChanged(object sender, EventArgs e)
        {
            if (checkBox_ack.Checked)
            {
                groupBox_120.Size = new Size(groupBox_show.Size.Width / 2, groupBox_show.Size.Height);
                groupBox_120.Location = new Point(groupBox_show.Size.Width / 2, 0);
            }
            else
            {
                groupBox_120.Size = new Size(groupBox_show.Size.Width, groupBox_show.Size.Height);
                groupBox_120.Location = new Point(0, 0);
            }

            groupBox_250.Size = new Size(groupBox_show.Size.Width / 2, groupBox_show.Size.Height);
            groupBox_250.Location = new Point(0, 0);
        }

        #region 日志记录、支持其他线程访问
        public delegate void LogAppendDelegate(Color color, string text);
        /// <summary> 
        /// 追加显示文本 
        /// </summary> 
        /// <param name="color">文本颜色</param> 
        /// <param name="text">显示文本</param> 
        public void LogAppend(Color color, string text)
        {
            richTextBox_250.AppendText("\n");
            richTextBox_250.SelectionColor = color;
            richTextBox_250.AppendText(text);
        }
        /// <summary> 
        /// 显示错误日志 
        /// </summary> 
        /// <param name="text"></param> 
        public void LogError(string text)
        {
            LogAppendDelegate la = new LogAppendDelegate(LogAppend);
            richTextBox_250.Invoke(la, Color.Red, DateTime.Now.ToString("HH:mm:ss ") + text);
        }
        /// <summary> 
        /// 显示警告信息 
        /// </summary> 
        /// <param name="text"></param> 
        public void LogWarning(string text)
        {
            LogAppendDelegate la = new LogAppendDelegate(LogAppend);
            richTextBox_250.Invoke(la, Color.Violet, DateTime.Now.ToString("HH:mm:ss ") + text);
        }
        /// <summary> 
        /// 显示信息 
        /// </summary> 
        /// <param name="text"></param> 
        public void LogMessage(string text)
        {
            LogAppendDelegate la = new LogAppendDelegate(LogAppend);
            richTextBox_250.Invoke(la, Color.Black, DateTime.Now.ToString("HH:mm:ss ") + text);
        }
        #endregion 

        private void button_DeviceID_Click(object sender, EventArgs e)
        {
            byte[] frameB = new byte[50];

            #region head
            frameB[0] = 0x55;
            frameB[1] = 0xAA;
            frameB[2] = 0x01;//协议版本
            frameB[3] = 0x0F;//头长度
            frameB[4] = 0x01;//应用类型 LMD ;LAIS
            frameB[5] = (byte)(17 & 0xFF);
            frameB[6] = (byte)(17 >> 8);
            frameB[7] = (byte)(1 & 0xFF);//framendex
            frameB[8] = (byte)(1 >> 8);
            frameB[9] = 0x09;//源设备
            frameB[10] = 0x07;//目的设备
            frameB[11] = 0x00;//是否需要应答
            frameB[12] = 0x00;//保留
            frameB[13] = 0x00;//保留
            frameB[14] = 0x00;//保留
            #endregion

            #region data
            frameB[15] = frameB[5];//数据长度
            frameB[16] = frameB[6];//数据长度
            frameB[17] = 0x09;//设备类型（源设备）
            frameB[18] = 0x01;//信息类型：实时信息
            frameB[19] = 0x01;//数据内容版本

            frameB[20] = 0x01;//lon 协议版本
            frameB[21] = 0x67;//lon frame : order 
            frameB[22] = 0x01;//lon frame : frameindex
            frameB[23] = 0x01;//lon frame : frameindex 
            frameB[24] = 0x01;//lon frame : JCH
            frameB[25] = 0x01;//lon frame : JCH 
            frameB[26] = 0x01;//lon frame : JCH 
            frameB[27] = 0x01;//lon frame : JCH 
            frameB[28] = 0x01;//lon frame : Device ID 
            frameB[29] = 0x01;//lon frame : Device ID

            frameB[30] = (byte)(Int32.Parse(textBox_DeviceID.Text));//lon frame : new Device ID
            frameB[31] = (byte)(Int32.Parse(textBox_DeviceID.Text) >> 8);//lon frame : new Device ID

            int offset = 32;
            #endregion

            //string[] dataStr = textBox6_data.Text.Split(new char[] {' ','\t','\r','\n' }, StringSplitOptions.RemoveEmptyEntries);

            #region 校验和
            frameB[offset] = 0;
            for (int i = 0; i < offset; i++)
            {
                frameB[offset] += frameB[i];
            }
            frameB[offset] = (byte)~frameB[offset];
            frameB[offset]++;
            offset++;
            #endregion

            IPEndPoint localIpep = new IPEndPoint(IPAddress.Parse(IP_120), 12376); // 本机IP，指定的端口号
            udpcSend = new UdpClient(localIpep);
            IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(IP_CID), 5555); // 发送到的IP地址和端口号

            udpcSend.Send(frameB, 33, remoteIpep);
            udpcSend.Close();
        }

        private void button_cmd_Click(object sender, EventArgs e)
        {

            byte[] frameB = new byte[50];

            #region application data

            int totalLen = 30;
            int datalen;
            byte cmd = 0x69;

            string[] dataStr = textBox6_data.Text.Split(new char[] {' ','\t','\r','\n' }, StringSplitOptions.RemoveEmptyEntries);            
            //for (int i = 0; i < dataStr.Length; i++)
            //{
            //    frameB[30 + i] = byte.Parse(dataStr[i], System.Globalization.NumberStyles.AllowHexSpecifier);
            //    offset++;
            //}
            cmd = byte.Parse(dataStr[0], System.Globalization.NumberStyles.AllowHexSpecifier);
            char[] dataASCII = dataStr[dataStr.Length-1].ToCharArray();
            for (int i = 0; i < dataASCII.Length; i++)
            {
                frameB[totalLen++] = (byte)dataASCII[i];
            }
            frameB[totalLen++] = 0;
            datalen = 15 + dataASCII.Length + 1;
            #endregion 

            #region head
            frameB[0] = 0x55;
            frameB[1] = 0xAA;
            frameB[2] = 0x01;//协议版本
            frameB[3] = 0x0F;//头长度
            frameB[4] = 0x01;//应用类型 LMD ;LAIS
            frameB[5] = (byte)(datalen & 0xFF);
            frameB[6] = (byte)(datalen >> 8);
            frameB[7] = (byte)(1 & 0xFF);//framendex
            frameB[8] = (byte)(1 >> 8);
            frameB[9] = 0x09;//源设备
            frameB[10] = 0x07;//目的设备
            frameB[11] = 0x01;//是否需要应答
            frameB[12] = 0x00;//保留
            frameB[13] = 0x00;//保留
            frameB[14] = 0x00;//保留
            #endregion

            #region data
            frameB[15] = frameB[5];//数据长度
            frameB[16] = frameB[6];//数据长度
            frameB[17] = 0x09;//设备类型（源设备）
            frameB[18] = 0x01;//信息类型：实时信息
            frameB[19] = 0x01;//数据内容版本

            frameB[20] = 0x01;//lon 协议版本
            frameB[21] = cmd;//lon frame : order 
            frameB[22] = 0x01;//lon frame : frameindex
            frameB[23] = 0x01;//lon frame : frameindex 
            frameB[24] = 0x01;//lon frame : JCH
            frameB[25] = 0x01;//lon frame : JCH 
            frameB[26] = 0x01;//lon frame : JCH 
            frameB[27] = 0x01;//lon frame : JCH 
            frameB[28] = 0x01;//lon frame : Device ID 
            frameB[29] = 0x01;//lon frame : Device ID
            #endregion

            
            #region 校验和
            frameB[totalLen] = 0;
            for (int i = 0; i < totalLen; i++)
            {
                frameB[totalLen] += frameB[i];
            }
            frameB[totalLen] = (byte)~frameB[totalLen];
            frameB[totalLen]++;
            totalLen++;
            #endregion

            IPEndPoint localIpep = new IPEndPoint(IPAddress.Parse(IP_120), 12376); // 本机IP，指定的端口号
            udpcSend = new UdpClient(localIpep);
            IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(IP_CID), 5555); // 发送到的IP地址和端口号

            udpcSend.Send(frameB, totalLen, remoteIpep);
            udpcSend.Close();
            textBox6_data.Focus();
        }

        private void textBox6_data_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
                button_cmd_Click(null, null);
                return;
        }

        private void button_ReadFile_Click(object sender, EventArgs e)
        {
            byte[] frameB = new byte[50];

            #region head
            frameB[0] = 0x55;
            frameB[1] = 0xAA;
            frameB[2] = 0x01;//协议版本
            frameB[3] = 0x0F;//头长度
            frameB[4] = 0x01;//应用类型 LMD ;LAIS
            frameB[5] = (byte)(17 & 0xFF);////////////////////////////////////////////////////
            frameB[6] = (byte)(17 >> 8);//////////////////////////////////////////////////////
            frameB[7] = (byte)(1 & 0xFF);//framendex
            frameB[8] = (byte)(1 >> 8);
            frameB[9] = 0x09;//源设备 TSC:09
            frameB[10] = 0x07;//目的设备 CID:07
            frameB[11] = 0x00;//是否需要应答
            frameB[12] = 0x00;//保留
            frameB[13] = 0x00;//保留
            frameB[14] = 0x00;//保留
            #endregion

            #region data
            frameB[15] = frameB[5];//数据长度
            frameB[16] = frameB[6];//数据长度
            frameB[17] = 0x09;//设备类型（源设备）
            frameB[18] = 0x01;//信息类型：实时信息
            frameB[19] = 0x01;//数据内容版本

            frameB[20] = 0x01;//lon 协议版本
            frameB[21] = 0x68;//lon frame : order /////////////////////////////////////////////////
            frameB[22] = 0x01;//lon frame : frameindex
            frameB[23] = 0x01;//lon frame : frameindex 
            frameB[24] = 0x01;//lon frame : JCH
            frameB[25] = 0x01;//lon frame : JCH 
            frameB[26] = 0x01;//lon frame : JCH 
            frameB[27] = 0x01;//lon frame : JCH 
            frameB[28] = 0x01;//lon frame : Device ID 
            frameB[29] = 0x01;//lon frame : Device ID

            frameB[30] = 0x00;
            frameB[31] = 0x00;

            int offset = 32;
            #endregion

            #region 校验和
            frameB[offset] = 0;
            for (int i = 0; i < offset; i++)
            {
                frameB[offset] += frameB[i];
            }
            frameB[offset] = (byte)~frameB[offset];
            frameB[offset]++;
            offset++;
            #endregion

            IPEndPoint localIpep = new IPEndPoint(IPAddress.Parse(IP_120), 12376); // 本机IP，指定的端口号
            udpcSend = new UdpClient(localIpep);
            IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(IP_CID), 5555); // 发送到的IP地址和端口号

            udpcSend.Send(frameB, offset, remoteIpep);
            udpcSend.Close();
        }

        private void button_readVersion_Click(object sender, EventArgs e)
        {
            byte[] frameB = new byte[50];

            #region head
            frameB[0] = 0x55;
            frameB[1] = 0xAA;
            frameB[2] = 0x01;//协议版本
            frameB[3] = 0x0F;//头长度
            frameB[4] = 0x01;//应用类型 LMD ;LAIS
            frameB[5] = (byte)(17 & 0xFF);////data length LSB
            frameB[6] = (byte)(17 >> 8);//////data length MSB
            frameB[7] = (byte)(1 & 0xFF);//framendex
            frameB[8] = (byte)(1 >> 8);
            frameB[9] = 0x09;//源设备 TSC:09
            frameB[10] = 0x07;//目的设备 CID:07
            frameB[11] = 0x00;//是否需要应答
            frameB[12] = 0x00;//保留
            frameB[13] = 0x00;//保留
            frameB[14] = 0x00;//保留
            #endregion

            #region data
            frameB[15] = frameB[5];//数据长度
            frameB[16] = frameB[6];//数据长度
            frameB[17] = 0x09;//设备类型（源设备）
            frameB[18] = 0x01;//信息类型：实时信息
            frameB[19] = 0x01;//数据内容版本

            frameB[20] = 0x01;//lon 协议版本
            frameB[21] = 0x64;//lon frame : order /////////////////////////////////////////////////
            frameB[22] = 0x01;//lon frame : frameindex
            frameB[23] = 0x00;//lon frame : frameindex 
            frameB[24] = 0x56;//lon frame : JCH
            frameB[25] = 0x78;//lon frame : JCH 
            frameB[26] = 0x9a;//lon frame : JCH 
            frameB[27] = 0xbc;//lon frame : JCH 
            frameB[28] = 0x01;//lon frame : Device ID 
            frameB[29] = 0x02;//lon frame : Device ID

            frameB[30] = 0x00;

            int offset = 31;
            #endregion

            #region 校验和
            frameB[offset] = 0;
            for (int i = 0; i < offset; i++)
            {
                frameB[offset] += frameB[i];
            }
            frameB[offset] = (byte)~frameB[offset];
            frameB[offset]++;
            offset++;
            #endregion

            IPEndPoint localIpep = new IPEndPoint(IPAddress.Parse(IP_120), 12376); // 本机IP，指定的端口号
            udpcSend = new UdpClient(localIpep);
            IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(IP_CID), 5555); // 发送到的IP地址和端口号

            udpcSend.Send(frameB, offset, remoteIpep);
            udpcSend.Close();
        }

        private void richTextBox_120_MouseClick(object sender, MouseEventArgs e)
        {
            button_cls.Focus();
        }

        private void richTextBox_250_MouseClick(object sender, MouseEventArgs e)
        {
            button_cls.Focus();
        }

        private void richTextBox_120_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            button_cls.Focus();
        }

        private void richTextBox_250_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            button_cls.Focus();
        }

        #region read file
        IPAddress remoteip = new IPAddress(new byte[] { 192, 168, 0, 110 });
        TcpClient conn;
        long starttick;
        long lasttick;
        byte[] filebuf = new byte[1024*1024];
        string PATH_DIR = Application.StartupPath + "\\file\\";
        string PATH_FILE = Application.StartupPath + "\\file\\" + "000";
        FileStream fs_receive;
        BinaryWriter w_receive;

        private void button_TCP_Click(object sender, EventArgs e)
        {
            #region filename
            if (!Directory.Exists(PATH_DIR))
                Directory.CreateDirectory(PATH_DIR);
            PATH_FILE = PATH_DIR +
                DateTime.Now.Year.ToString() +
                DateTime.Now.Month.ToString("00") +
                DateTime.Now.Day.ToString("00") +
                DateTime.Now.Hour.ToString("00") +
                DateTime.Now.Minute.ToString("00") +
                DateTime.Now.Second.ToString("00");// +".fpa";
            if (File.Exists(PATH_FILE))
                File.Delete(PATH_FILE);
            #endregion

            #region filewriter
            //FileStream fs1 = new FileStream(path_file, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            //BinaryWriter w1 = new BinaryWriter(fs1);
            //fs1.Seek(0, SeekOrigin.End);
            #endregion
            //int timecount = 0;
            //int packageLen = 0;
            //
            this.Invoke(new MethodInvoker(delegate
            {
                button_TCP.Enabled = false;
            }));
            conn = new TcpClient();
            if (!conn.Connected)
                conn.Connect(remoteip, 7003);
            NetworkStream ns = conn.GetStream();
            if(conn.Connected)
                ns.BeginRead(filebuf, 0, filebuf.Length, new AsyncCallback(myReadCallBack), ns);
            //IAsyncResult result = ns.BeginRead(filebuf, 0, filebuf.Length,new AsyncCallback(myReadCallBack),ns);


            #region filewriter
            fs_receive = new FileStream(PATH_FILE, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            w_receive = new BinaryWriter(fs_receive);
            fs_receive.Seek(0, SeekOrigin.End);
            #endregion


            starttick = DateTime.Now.Ticks;
            lasttick = DateTime.Now.Ticks;
            //disable
            #region read data stream
            //while (timecount < 3)
            //{
            //    if (!ns.DataAvailable)
            //    {
            //        timecount++;
            //        Thread.Sleep(500);
            //        continue;
            //    }

            //    timecount = 0;
            //    byte[] buffer = new byte[conn.ReceiveBufferSize];
            //    //读取进来的流
            //    int bytesRead = 0;
            //    if (ns.DataAvailable)
            //        bytesRead = ns.Read(buffer, 0, conn.ReceiveBufferSize);
            //    packageLen += bytesRead;
            //    //接收的数据转换成字符串
            //    //string dataReceived = Encoding.UTF8.GetString(buffer, 0, bytesRead);
            //    richTextBox_120.AppendText(packageLen.ToString() + "\r\n");

            //    #region save file

            //    w1.Write(buffer, 0, bytesRead);

            //    #endregion
            //}

            //w1.Close();
            //fs1.Close();
            #endregion

        }
        //这个返回值result 可以用来控制对异步线程的同步
        public void myReadCallBack(IAsyncResult ar)
        {
            NetworkStream ns = (NetworkStream)ar.AsyncState;
            int numberOfBytesRead = 0;
            if (ns.CanRead)
                numberOfBytesRead = ns.EndRead(ar);

            this.Invoke(new MethodInvoker(delegate
            {
                #region box display
                richTextBox_120.AppendText("call back,receive length:".PadRight(30) + numberOfBytesRead.ToString().PadLeft(8) +
                                            "  " +
                                            ((float)(DateTime.Now.Ticks - lasttick) / 10000).ToString("f2").PadLeft(8) +
                                            " ms\r\n");
                richTextBox_120.ScrollToCaret();
                #endregion
            }));
            if (numberOfBytesRead > 0)
            {
                lasttick = DateTime.Now.Ticks;
                w_receive.Write(filebuf, 0, numberOfBytesRead);
            }

            if (numberOfBytesRead > 0)
                ns.BeginRead(filebuf, 0, filebuf.Length, new AsyncCallback(myReadCallBack), ns);
            else
            {
                w_receive.Close();
                fs_receive.Close();
                conn.Client.Disconnect(false);
                this.Invoke(new MethodInvoker(delegate
                {
                    button_TCP.Enabled = true;
                }));
                filecheck(PATH_FILE, lasttick - starttick);
            }

        }
        public void filecheck(string fpath,long tick)
        {
            const int BOFEI_HEAD_LEN = 7;
            const int HEAD_LEN = 200;
            const int TOTAL_HEAD_LEN = BOFEI_HEAD_LEN + HEAD_LEN;
            const int H_TOLL_O = BOFEI_HEAD_LEN + 6;
            const int H_D_ID_O = BOFEI_HEAD_LEN + 10;
            const int H_TIME_O = BOFEI_HEAD_LEN + 20;
            const int H_STSL_O = BOFEI_HEAD_LEN + 52 + 36 * 0;
            const int H_ST8L_O = BOFEI_HEAD_LEN + 52 + 36 * 1;
            const int H_ANAL_O = BOFEI_HEAD_LEN + 52 + 36 * 2;
            const int H_POWL_O = BOFEI_HEAD_LEN + 52 + 36 * 3;

            if (!File.Exists(fpath))
                return;

            FileStream fs_or = new FileStream(fpath, FileMode.Open, FileAccess.Read);
            BinaryReader br_or = new BinaryReader(fs_or);

            long totalL = fs_or.Length;

            this.Invoke(new MethodInvoker(delegate
            {
                #region box display
                float speed = ((float)totalL * 10000000 / tick) / 1024;
                richTextBox_120.AppendText("\r\n\r\n\r\n"+
                                            "SIZE:".PadRight(30) + ((float)totalL / 1024 / 1024).ToString("f4").PadLeft(8) + " MBytes\r\n" +
                                           "TIME:".PadRight(30) + ((float)tick / 10000000).ToString("f2").PadLeft(8) + " 秒\r\n" +
                                           "Speed:".PadRight(30) + speed.ToString("f2").PadLeft(8) + " KBps\r\n");
                richTextBox_120.ScrollToCaret();
                #endregion
            }));

            if (totalL < (BOFEI_HEAD_LEN+HEAD_LEN))
                return;
            byte sumcheck = 0;
            byte[] filehead = br_or.ReadBytes(TOTAL_HEAD_LEN);
            for (int i = 0; i < HEAD_LEN; i++)
                sumcheck += filehead[BOFEI_HEAD_LEN+i];

            if ((totalL - BOFEI_HEAD_LEN) != get32(filehead[H_TOLL_O + 0],
                                                    filehead[H_TOLL_O + 1],
                                                    filehead[H_TOLL_O + 2],
                                                    filehead[H_TOLL_O + 3])
                )
            {
                MessageBox.Show("lengt error1");
                return;
            }

            #region analy DIR
            string newDir = PATH_DIR;
            for (int i = 0; filehead[H_D_ID_O + i] != '\0'; i++)
            {
                if (filehead[H_D_ID_O + i] >= '0' && filehead[H_D_ID_O + i] <= '9')
                    newDir += (char)filehead[H_D_ID_O + i];
                else
                    break;
            }
            newDir += "\\";
            for (int i = 0; filehead[H_TIME_O + i] != '\0'; i++)
            {
                if (
                    (filehead[H_TIME_O + i] >= '0' && filehead[H_TIME_O + i] <= '9') ||
                    filehead[H_TIME_O + i] == ' ' ||
                    filehead[H_TIME_O + i] == '-' ||
                    filehead[H_TIME_O + i] == '!'
                    )
                    newDir += (char)filehead[H_TIME_O + i];
                else
                    break;
            }
            newDir += "\\";
            #endregion

            if (!Directory.Exists(newDir))
                Directory.CreateDirectory(newDir);

            #region creat sts st8 ana pow file
            string stspath = newDir + "000.STS";
            string st8path = newDir + "001.STS";
            string anapath = newDir + "002.ANA";
            string powpath = newDir + "003.POW";
            if (File.Exists(stspath))
                File.Delete(stspath);
            if (File.Exists(st8path))
                File.Delete(st8path);
            if (File.Exists(anapath))
                File.Delete(anapath);
            if (File.Exists(powpath))
                File.Delete(powpath);

            int stsLen = get32(filehead[H_STSL_O], filehead[H_STSL_O + 1], filehead[H_STSL_O + 2], filehead[H_STSL_O + 3]);
            int st8Len = get32(filehead[H_ST8L_O], filehead[H_ST8L_O + 1], filehead[H_ST8L_O + 2], filehead[H_ST8L_O + 3]);
            int anaLen = get32(filehead[H_ANAL_O], filehead[H_ANAL_O + 1], filehead[H_ANAL_O + 2], filehead[H_ANAL_O + 3]);
            int powLen = get32(filehead[H_POWL_O], filehead[H_POWL_O + 1], filehead[H_POWL_O + 2], filehead[H_POWL_O + 3]);
            if (stsLen > 0)
            {
                #region creat sts
                byte[] buf = br_or.ReadBytes(stsLen);
                for (int i = 0; i < buf.Length; i++)
                    sumcheck += buf[i];

                FileStream fs_subfile = new FileStream(newDir + "000.STS", FileMode.Create, FileAccess.Write);
                BinaryWriter w = new BinaryWriter(fs_subfile);
                w.Write(buf);
                w.Close();
                fs_subfile.Close();
                #endregion
            }
            if (st8Len > 0)
            {
                #region creat st8
                byte[] buf = br_or.ReadBytes(st8Len);
                for (int i = 0; i < buf.Length; i++)
                    sumcheck += buf[i];

                FileStream fs_subfile = new FileStream(newDir + "001.STS", FileMode.Create, FileAccess.Write);
                BinaryWriter w = new BinaryWriter(fs_subfile);
                w.Write(buf);
                w.Close();
                fs_subfile.Close();
                #endregion
            }
            if (anaLen > 0)
            {
                #region ana
                byte[] buf = br_or.ReadBytes(anaLen);
                for (int i = 0; i < buf.Length; i++)
                    sumcheck += buf[i];

                FileStream fs_subfile = new FileStream(newDir + "002.ANA", FileMode.Create, FileAccess.Write);
                BinaryWriter w = new BinaryWriter(fs_subfile);
                w.Write(buf);
                w.Close();
                fs_subfile.Close();
                #endregion
            }
            if (powLen > 0)
            {
                #region pow
                byte[] buf = br_or.ReadBytes(powLen);
                for (int i = 0; i < buf.Length; i++)
                    sumcheck += buf[i];

                FileStream fs_subfile = new FileStream(newDir + "003.POW", FileMode.Create, FileAccess.Write);
                BinaryWriter w = new BinaryWriter(fs_subfile);
                w.Write(buf);
                w.Close();
                fs_subfile.Close();
                #endregion
            }
            #endregion


            byte[] left = br_or.ReadBytes(2);
            if (left.Length != 1)
                MessageBox.Show("lengt error");
            sumcheck += left[0];
            if (sumcheck != 0)
                MessageBox.Show("sum check error");

            br_or.Close();
            fs_or.Close();
            return;
        }

        public int get32(byte a, byte b, byte c, byte d)
        {
            return ((int)a << 0) + ((int)b << 8) + ((int)c << 16) + ((int)d << 24);
        }
        #endregion

        private void button_disconnect_Click(object sender, EventArgs e)
        {
            //if (conn.Connected)
                conn.Close();
        }

        private void button_UpGrade_Click(object sender, EventArgs e)
        {
            if (isRunning)
                button_start_Click(null,null);
            Form_Main ug = new Form_Main();
            //ug.Show(this);//允许切回母窗口
            ug.ShowDialog(this);//不允许切回母窗口
        }

        

      


        














        //EOF-----------------------------------------------------------------------------
    }
}
